home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir41 / wcpu050.zip / WHICHCPU.PAS < prev    next >
Pascal/Delphi Source File  |  1993-03-12  |  11KB  |  344 lines

  1. { WhichCPU - Yet another CPU-Identifier
  2.   1992,1993  by Michael Holin
  3.                                            this is Public Domain
  4.  
  5.   Thanks to
  6.  
  7.   Michael Tischer and many others,         for the base-cpu-id-routine
  8.   Ted Forgeron & Pat Shea,                 for the base-npu-id-routine
  9.   Hans-Ullrich Siehl,                      for his RapidCAD
  10.   Roland Gorisch,                          for his Cyrix486
  11.   c't Magazin,                             for many interesting articles
  12.   PC-Professional Magazin                  for details on Pentium
  13.   Andrew Rossmann,                         for his SYSID+
  14.                                            (maybe soon comes a version, which
  15.                                             detects 386sx and RapidCAD  ;-)
  16. }
  17.  
  18. {$F+,I-,R-,D-,S-,A+,V-}
  19. {$L wcpu.obj}
  20. uses dos,tpstring;             {only used for byte to hex conversion}
  21. const ver:string[4]='0.50';
  22. var ret,ax,cpu,puffseg,puffofs,i,j,ccode,ncode:word;
  23.     coproemu,weitek:boolean;
  24.     regs:registers;
  25.     p:pointer;
  26.  
  27.  
  28. function CoPro:word;      external; {8087, 80287, 80387 ?}
  29. function GetProz:word;    external; {gets prozessortyp}
  30.  
  31. {works only on 80386+}
  32. function DXorSX:word;     external; {Memory-Access with LODSD}
  33.  
  34. procedure StartTimer;      {Set Timer to 65536}
  35. begin                      {dec every 838ns by one}
  36.   inline($FA/$B0/$34/$E6/$43/$EB/$00/$B0/$00/$E6/$40/$EB/$00/$E6/$40);
  37. end;
  38.  
  39.  
  40. function ReadTimer:word;
  41. begin
  42.   port[$43]:=0;
  43.   ReadTimer:=65535-port[$40] shl 8-port[$40];
  44.   inline($FB);
  45. end;
  46.  
  47. procedure MaskRev;  {get CPU-Revision on new BIOSes}
  48. begin
  49.   regs.ax:=$C910;
  50.   intr($15,regs);
  51.   if regs.ah=0 then begin
  52.     write(' Rev.',hexb(regs.cl));
  53.   end;
  54. end;              {byte to hex from TPString-Unit}
  55.  
  56.  
  57. procedure info;
  58. begin
  59.   if (paramstr(1)='cpu') or (paramstr(1)='CPU') then ret:=1;
  60.   if (paramstr(1)='npu') or (paramstr(1)='NPU') then ret:=2;
  61.   if paramstr(1)='?' then begin
  62.      writeln(#10'for batchfiles use: WhichCPU cpu          to return CPU-Code as errorlevel');
  63.      writeln('                    WhichCPU npu          to return NPU-Code as errorlevel');
  64.      writeln(#10'CPU : 88,86,V20,V30,188,186,286,386sx,-dx,RapidCAD,486sx,-dx,-slc,-dlc,Pentium');
  65.      writeln('ERRL:  0, 1,  2,  3,  4,  5,  6,    7,  8,       9,   10, 11,  12, 13 ,     14');
  66.      writeln('NPU : none,software,87,287,387');
  67.      writeln('ERRL:    0,       1, 2,  3,  4');
  68.      writeln(#10'WhichCPU is an extract from the outstanding PC-Systeminfo-Benchmark-Program');
  69.      writeln('PC-CONFIG (c) 1989,1993 by Michael Holin (available only in german language)');
  70.      writeln('for further information write, call, fax, or mail to:');
  71.      writeln(#10'Michael Holin           Phone   : +49 5323 3350');
  72.      writeln('PO-Box 1146             Fax     : +49 5323 3380');
  73.      writeln('3392 Clausthal          Fido    : 2:241/3431');
  74.      writeln('West-Germany            Internet: himh@sun.rz.tu-clausthal.de');
  75.      writeln(#10'all these numbers and addresses are valid until jun. 1993');
  76.      halt;
  77.    end;
  78. end;
  79.  
  80.  
  81. procedure TestCPU;
  82. var i,j,fa:word;
  83.     z1,z2:longint;
  84.     buszyklus:byte;
  85. begin
  86.   case CPU of
  87.   0:begin
  88.       write('8088');
  89.       ccode:=0;
  90.     end;
  91.   1:begin
  92.       write('8086');
  93.       ccode:=1;
  94.     end;
  95.   2:begin
  96.       write('NEC V20');
  97.       ccode:=2;
  98.     end;
  99.   3:begin
  100.       write('NEC V30');
  101.       ccode:=3;
  102.     end;
  103.   4:begin
  104.       write('80188');
  105.       ccode:=4;
  106.     end;
  107.   5:begin
  108.       write('80186');
  109.       ccode:=5;
  110.     end;
  111.   6:begin
  112.       write('80286');
  113.       ccode:=6;
  114.     end;
  115.   7:begin
  116.       if true then begin
  117.         mem[puffseg:Puffofs+0]:=$B9;
  118.         mem[puffseg:Puffofs+1]:=$7F;
  119.         mem[puffseg:Puffofs+2]:=$7F;       {Loop cx slower than}
  120.         mem[puffseg:Puffofs+3]:=$90;       {dec cx+jne ? -> RapidCAD}
  121.         mem[puffseg:Puffofs+4]:=$E2;
  122.         mem[puffseg:Puffofs+5]:=$FE;
  123.         mem[puffseg:Puffofs+6]:=$CF;
  124.         starttimer;
  125.         intr($88,regs);               {start the loop}
  126.         z1:=readtimer;                {get time for doing that}
  127.         mem[puffseg:Puffofs+0]:=$B9;
  128.         mem[puffseg:Puffofs+1]:=$7F;
  129.         mem[puffseg:Puffofs+2]:=$7F;
  130.         mem[puffseg:Puffofs+3]:=$49;
  131.         mem[puffseg:Puffofs+4]:=$75;
  132.         mem[puffseg:Puffofs+5]:=$FD;
  133.         mem[puffseg:Puffofs+6]:=$CF;
  134.         starttimer;
  135.         intr($88,regs);
  136.         z2:=readtimer;
  137.         if (z1*10) div (z2 div 10)>112 then begin    {difference ?}
  138.           write('RapidCAD');
  139.           ccode:=9;
  140.           cpu:=10;
  141.           end
  142.         else begin
  143.         write('80386');         {distinguish between sx and dx}
  144.         memw[$40:$f0]:=$2000;   { $2000 DWords read at}
  145.         memw[$40:$f2]:=1;       {Offset 1}
  146.         memw[$40:$f4]:=0;       {Segment 0}
  147.         i:=DXorSX;
  148.         i:=DXorSX;              {twice, to fetch from cache}
  149.         memw[$40:$f2]:=2;       {same at Offset 2}
  150.         j:=DXorSX;
  151.         if j+90<i then begin    {difference ?}
  152.            write('sx');
  153.            ccode:=7;
  154.           end
  155.         else begin
  156.            write('dx');
  157.            ccode:=8;
  158.         end;
  159.         end;
  160.       end else write('80386');
  161.     Maskrev;
  162.     end;
  163.   8:begin
  164.       mem[puffseg:Puffofs+0]:=$B8;
  165.       mem[puffseg:Puffofs+1]:=$AA;
  166.       mem[puffseg:Puffofs+2]:=$AA;
  167.       mem[puffseg:Puffofs+3]:=$BB;
  168.       mem[puffseg:Puffofs+4]:=$55;
  169.       mem[puffseg:Puffofs+5]:=$55;
  170.       for i:=0 to 200 do memw[puffseg:Puffofs+6+i*2]:=$E3F7; {MUL}
  171.       mem[puffseg:Puffofs+8+200*2]:=$CF;
  172.       starttimer;
  173.       intr($88,regs);               {200 MULs}
  174.       z1:=readtimer;                {get time for doing that}
  175.       mem[puffseg:Puffofs+0]:=$B8;
  176.       mem[puffseg:Puffofs+1]:=$AA;
  177.       mem[puffseg:Puffofs+2]:=$AA;
  178.       mem[puffseg:Puffofs+3]:=$BB;
  179.       mem[puffseg:Puffofs+4]:=$55;
  180.       mem[puffseg:Puffofs+5]:=$55;
  181.       for i:=0 to 200 do memw[puffseg:Puffofs+6+i*2]:=$0AD4; {AAM}
  182.       mem[puffseg:Puffofs+8+200*2]:=$CF;
  183.       starttimer;
  184.       intr($88,regs);               {200 AAMs}
  185.       z2:=readtimer;                {get time for doing that}
  186.       if (longint(z1)*8)>(longint(z2)*5) then begin
  187.         write('80486');
  188.         if (copro>0) and not coproemu then begin
  189.           write('dx');            {486 with real copro ?}
  190.           ccode:=11;
  191.         end
  192.         else begin                {without, or with 'soft'-copro}
  193.           write('sx');
  194.           ccode:=10;
  195.         end;
  196.         MaskRev;
  197.         end
  198.       else begin
  199.       write('Cyrix 486');
  200.       memw[$40:$f0]:=$2000;   { $2000 DWords read at}
  201.       memw[$40:$f2]:=1;       {Offset 1}
  202.       memw[$40:$f4]:=0;       {Segment 0}
  203.       i:=DXorSX;
  204.       i:=DXorSX;              {twice, to fetch from cache}
  205.       memw[$40:$f2]:=2;       {same at Offset 2}
  206.       j:=DXorSX;
  207.       if j+90<i then begin    {difference ?}
  208.          write('slc');
  209.          ccode:=12;
  210.         end
  211.       else begin
  212.          write('dlc');
  213.          ccode:=13;
  214.       end;
  215.       end;
  216.     end;
  217.   9:begin
  218.       write('Pentium');
  219.       ccode:=14;
  220.     end;
  221.   else write('???');            {shouldn't come to this point}
  222.   end;
  223.   writeln;
  224. end;
  225.  
  226.  
  227. function checkiit: boolean;
  228. var sw87,cw87: word;
  229. begin
  230.   inline(
  231.     $D9/$7E/<cw87/      { FSTCW cw87[BP]       ; store control word }
  232.     $DB/$E3/            { FINIT                                     }
  233.     $DB/$E8/            { FSBP0                ; set bank 0         }
  234.     $D9/$EE/            { FLDZ                 ; load zero          }
  235.     $DB/$E3/            { FINIT                                     }
  236.     $DB/$EB/            { FSBP1                ; set bank 1         }
  237.     $D9/$E8/            { FLD1                 ; load 1             }
  238.     $DB/$E8/            { FSBP0                ; set bank 0         }
  239.     $D9/$E4/            { FTST                 ; test zero          }
  240.     $DD/$7E/<sw87/      { FSTSW sw87[BP]       ; store status word  }
  241.     $DB/$E3/            { FINIT                                     }
  242.     $D9/$6E/<cw87);     { FLDCW cw87[BP]       ; load control word  }
  243.   checkiit:= (sw87 and $4100)=$4000;
  244. end;
  245.  
  246.  
  247. procedure testnpu;
  248. var z1,z2,z3:word;
  249. begin
  250.   if (cpu=10) or (ccode=14) then begin   {Rapidcad has it's own copro, but}
  251.     write('build in');                   {crashes in the copro-Routine ???}
  252.     exit;                                {Maybe not a real 80387???}
  253.   end;
  254.   ax:=copro;                  {witch kind of copro}
  255.   if (ccode=11) and (ax>0) and not coproemu then begin
  256.     write('build in');        {486dx}
  257.     exit;
  258.   end;
  259.   case ax of
  260.     0:begin
  261.        write('none');
  262.        ncode:=0;
  263.       end;
  264.     1:begin
  265.        write('8087');
  266.        ncode:=2;
  267.       end;
  268.     2:begin
  269.        write('80287');
  270.        ncode:=3;
  271.       end;
  272.     3:begin
  273.        write('80387');
  274.        ncode:=4;
  275.       end;
  276.   end;
  277.   if ax>1 then if checkiit then write(' (IIT)');
  278.   if coproemu then begin
  279.     write('-Emulation');
  280.     ncode:=1;
  281.   end;
  282.   writeln;
  283.   if ax=0 then exit;
  284.   if paramstr(1)<>'debug' then exit;
  285.  
  286.   {the following code is for the future, to distinguish between}
  287.   {some NPUs (IIT, Cyrix, AMD...)}
  288.  
  289.   mem[puffseg:Puffofs+0]:=$CF;    {IRET}
  290.   starttimer;
  291.   intr($88,regs);
  292.   z3:=readtimer;
  293.   mem[puffseg:Puffofs+4]:=$CF;
  294.   starttimer;
  295.   intr($88,regs);
  296.   z1:=readtimer;
  297.   mem[puffseg:Puffofs+0]:=$DB;    {FINIT}
  298.   mem[puffseg:Puffofs+1]:=$E3;
  299.   mem[puffseg:Puffofs+2]:=$D9;    {FLDL2T}
  300.   mem[puffseg:Puffofs+3]:=$E9;
  301.   mem[puffseg:Puffofs+4]:=$D9;    {4xFSQRT}
  302.   mem[puffseg:Puffofs+5]:=$FA;
  303.   mem[puffseg:Puffofs+6]:=$D9;
  304.   mem[puffseg:Puffofs+7]:=$FA;
  305.   mem[puffseg:Puffofs+8]:=$D9;
  306.   mem[puffseg:Puffofs+9]:=$FA;
  307.   mem[puffseg:Puffofs+10]:=$D9;
  308.   mem[puffseg:Puffofs+11]:=$FA;
  309.   mem[puffseg:Puffofs+12]:=$D9;
  310.   mem[puffseg:Puffofs+13]:=$FA;
  311.   mem[puffseg:Puffofs+14]:=$CF;
  312.   starttimer;
  313.   intr($88,regs);
  314.   z2:=readtimer;
  315.   writeln(z3,' ',z1,' ',z2);
  316. end;
  317.  
  318.  
  319. begin
  320.   ret:=0;
  321.   ccode:=0;
  322.   ncode:=0;
  323.   writeln(#10'WhichCPU V'+ver+' (c) by Michael Holin     //    Public Domain');
  324.   writeln('WhichCPU ? for info');
  325.   info;
  326.   writeln(#10'Looking for: 8088,8086,V20,V30,80188,80186,80286,80386sx,-dx,RapidCAD');
  327.   writeln(   '             80486sx,-dx,-slc,-dlc,Pentium');
  328.   getmem(p,10000);              {get Puffer}
  329.   Puffseg:=seg(p^);
  330.   PuffOfs:=ofs(p^);
  331.   SetIntVec($88,ptr(PuffSeg,Puffofs));  {set Interrupt to Puffer}
  332.   write('CPU found  : ');
  333.   ax:=getproz;
  334.   coproemu:=ax and 32=32;
  335.   cpu     :=ax and 15;
  336.   testcpu;
  337.   write('NPU found  : ');
  338.   testnpu;
  339.   case ret of
  340.     1:halt(ccode);
  341.     2:halt(ncode);
  342.   end;
  343. end.
  344.